import hashlib
import json
import os.path

from urllib import parse as urlparse
import urllib.parse
from urllib.parse import quote
# from urlparse import urlparse


import werkzeug
from flask import Blueprint, request, render_template, redirect, url_for, jsonify, session, g, make_response, send_file, \
    Response, send_from_directory
from flask_restful import Api, Resource, reqparse, inputs, fields, marshal, marshal_with
from sqlalchemy import or_, and_
from werkzeug.security import generate_password_hash, check_password_hash

from datamp.interface.models import DataStandard
from datamp.user.models import *
from ext import db
from werkzeug.utils import secure_filename
from werkzeug.datastructures import FileStorage
from settings import Config

from flask_jwt_extended import (create_access_token, create_refresh_token, jwt_required, get_jwt_identity, get_jwt)
# 加载配置文件
from settings import Config

# from urllib.parse import quote
import unicodedata
from werkzeug.urls import url_quote

interface_bp = Blueprint('interface', __name__, url_prefix='/interface', template_folder='templates')

required_login_list = ['/interface/st', '/interface/set', '/interface/mon']

api = Api(interface_bp)

standard_parser = reqparse.RequestParser()
# standard_parser.add_argument('standardname', type=str, help='标准名不对', location=['form', 'args','json','files'])
standard_parser.add_argument('standard_content', type=werkzeug.datastructures.FileStorage, help='标准内容不对不对',
                             location=['form', 'args', 'json', 'files'])
standard_parser.add_argument('standard_style', type=str, help='标准类型不对不对', location=['form', 'args', 'json', 'files'])
standard_parser.add_argument('standard_publisher', type=str, help='标准发布者不对不对',
                             location=['form', 'args', 'json', 'files'])
standard_parser.add_argument('standard_introduction', type=str, help='标准简介不对不对',
                             location=['form', 'args', 'json', 'files'])

standard_download_parser = reqparse.RequestParser()
standard_download_parser.add_argument('standard_name', type=str, help='标准名不对',
                                      location=['form', 'args', 'json', 'files'])


# 钩子函数
@interface_bp.before_app_first_request
def first_request():
    print('before_app_first_request')


# 钩子函数
@interface_bp.before_app_request
def before_request1():
    print('before_app_request', request.path)
    if request.path in required_login_list:
        id = session.get('uid')
        if not id:
            return render_template('login.html')
        else:
            user = StudentInfo.query.get(id)
            # g对象，本次请求的对象
            g.user = user


# ------数据与接口管理------
# 1. 规范管理

# ---直接传输无minio注册标准---
# 允许的扩展名
ALLOWED_EXTENSIONS = ['jpg', 'png', 'gif', 'bmp', 'pdf']


class DataStandardUpload(Resource):
    def post(self):
        args = standard_parser.parse_args()
        standard_content = args.get('standard_content')
        standard_name = standard_content.filename
        standard_style = args.get('standard_style')
        standard_publisher = args.get('standard_publisher')
        print(standard_publisher)
        print(type(standard_publisher))
        standard_introduction = args.get('standard_introduction')
        print(standard_name)
        print(type(standard_name))
        standard_content.save(os.path.join('static/standard/', standard_name))
        suffix = standard_name.rsplit('.')[-1]
        print(suffix)
        standard_publishers = DataStandard.query.filter(
            and_(DataStandard.standardname == standard_name,
                 DataStandard.standard_publisher == standard_publisher)).all()
        if standard_publishers:
            return jsonify({'code': 1,
                            'msg': '该发布者已发布过同名标准，上传失败',
                            'standard_name': standard_name,
                            'standard_publisher': standard_publisher
                            })
        else:
            # 与模型结合
            standard = DataStandard()
            standard.standard_name = standard_name
            standard.standard_style = standard_style
            standard.standard_publisher = standard_publisher
            standard.standard_introduction = standard_introduction
            if suffix in ALLOWED_EXTENSIONS:
                # icon_name = secure_filename(icon_name)  # 保证文件名是符合python的命名规则
                file_path = os.path.join(Config.UPLOAD_ICON_DIR, standard_name)
                standard.standard_content = file_path
                # 添加
                db.session.add(standard)
                # 提交
                db.session.commit()
                return jsonify({'code': 0, 'msg': '上传文件成功',
                                'data': {
                                    'file_path': file_path,
                                    'standard_name': standard_name,
                                    'standard_publisher': standard_publisher
                                }
                                })
            else:
                return jsonify({'code': 1, 'msg': '上传文件失败'})


api.add_resource(DataStandardUpload, '/DataStandardUpload')


# --标准文件查询返回前端--
class StandardShow(Resource):
    def post(self):
        args = standard_download_parser.parse_args()
        filename = args.get('standard_name')
        print(filename)
        print(type(filename))

        aa = filename.rsplit('.')[0]
        print(aa)
        dir_path = os.path.join(Config.UPLOAD_ICON_DIR,
                                filename)  # 这里是下在目录，从工程的根目录写起，比如你要下载static/js里面的js文件，这里就要写“static/js”
        print(dir_path)
        response = make_response(open(dir_path, 'rb').read())
        response.headers["Content-type"] = "application/pdf;charset=UTF-8"
        response.headers["Content-Disposition"] = "attachment; filename={0}; filename*=utf-8''{0}".format(
            quote(filename))

        standards = DataStandard.query.filter(DataStandard.standard_name == filename).all()
        print(standards)
        load_list = []
        data_dict = {}
        for standard in standards:
            aa = {'standard_id': standard.id,
                  'standard_name': standard.standard_name,
                  'date_time': standard.date_time,
                  'standard_style': standard.standard_style,
                  'standard_publisher': standard.standard_publisher,
                  'update_time': standard.update_time,
                  'standard_introduction': standard.standard_introduction
                  }
            data_dict.update(aa)
            load_list.append(data_dict)
            data_dict = {}
        return jsonify({'msg': '获取成功',
                        'status': 200,
                        'data': load_list
                        })
        # response = make_response(send_static_file(standard, attachment_filename=filename))
        # response.headers['Content-Type'] = 'application/pdf'
        # return response  # as_attachment=True 一定要写，不然会变成打开，而不是下载


api.add_resource(StandardShow, '/StandardShow')


# --标准文件下载返回前端--
class StandardDownload(Resource):
    def post(self):
        args = standard_download_parser.parse_args()
        filename = args.get('standard_name')
        print(filename)
        print(type(filename))
        aa = filename.rsplit('.')[0]
        print(aa)
        dir_path = os.path.join(Config.UPLOAD_ICON_DIR)  # 这里是下在目录，从工程的根目录写起，比如你要下载static/js里面的js文件，这里就要写“static/js”
        print(dir_path)
        response = make_response(send_from_directory(dir_path, filename))
        response.headers["Content-Disposition"] = "attachment; filename={0}; filename*=utf-8''{0}".format(
            quote(filename))
        return response


api.add_resource(StandardDownload, '/StandardDownload')


# 2. 接口配置
@interface_bp.route('/interface/setting')
def api_setting():
    return render_template("setting.html")


# 3. 数据与接口监测
@interface_bp.route('/interface/monitor')
def api_monitor():
    return render_template("monitor.html")
